//
// Created by 高森森 on 2022/1/10.
//

#include <queue>
#include <numeric>
#include <memory.h>
#include "Solution1.h"

bool Solution1::validPath(int n, vector<vector<int> > &edges, int start, int end) {
    if(n==1||start==end)
        return true;
    vector<vector<pair<int, bool>>>matrix(n);
    for(int i=0;i<edges.size();i++)
    {
        matrix[edges[i][0]].push_back(make_pair(edges[i][1],false));
        matrix[edges[i][1]].push_back(make_pair(edges[i][0],false));
    }
    queue<int>que;
    que.push(start);
    while(!que.empty()){
        int start=que.front();
        que.pop();
        for(int i=0;i<matrix[start].size();i++)
        {
            if(matrix[start][i].second)
                continue;
            if(matrix[start][i].first!=end)
            {
                matrix[start][i].second= true;
                int y=matrix[start][i].first;
                que.push(y);
            }else{
                return true;
            }
        }
    }
    return false;
}
bool Solution1::validPath2(int n, vector<vector<int> > &edges, int start, int end) {
    if(n==1||start==end)
        return true;
    int fa[n],rank[n];
    iota(fa,fa+n,0);
    memset(rank,1, sizeof(rank));
    for(auto edge:edges){
        merge(edge[0],edge[1],fa,rank);
    }
    return find(start,fa)==find(end,fa);
}

int Solution1::find(int x, int *fa) {
    if(x==fa[x])
        return x;
    else{
        fa[x]=find(fa[x],fa);//将沿途的所有节点的父结点都设置为根节点
        return fa[x];
    }
}
void Solution1::merge(int i, int j, int *fa, int *rank) {
    int x=find(i,fa);
    int y=find(j,fa);
    //将高度低的合并到高度高的树上，不会增加树得深度
    if(rank[x]<=rank[y])
        fa[x]=y;
    else
        fa[y]=x;
    if(rank[x]==rank[y]&&x!=y){
        rank[y]++;
    }
}